package online.flowerinsnow.minecraft.bukkit.manhunt.listener;

import online.flowerinsnow.minecraft.bukkit.manhunt.config.ManhuntConfiguration;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;

import java.util.Random;

public class FastMineListener implements Listener {
    private static final Random RANDOM = new Random();
    @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
    public void onBreak(BlockBreakEvent e) {
        if (!ManhuntConfiguration.Fun.fastMine) return;
        ItemStack item = e.getPlayer().getInventory().getItemInMainHand();
        Block block = e.getBlock();
        switch (block.getType()) {
            case IRON_ORE, DEEPSLATE_IRON_ORE -> {
                block.setType(Material.AIR);
                doIronDrop(item, block);
                e.setCancelled(true);
            }
            case GOLD_ORE, DEEPSLATE_GOLD_ORE -> {
                block.setType(Material.AIR);
                e.setCancelled(true);
                doGoldDrop(item, block);
            }
            case COPPER_ORE, DEEPSLATE_COPPER_ORE -> {
                block.setType(Material.AIR);
                e.setCancelled(true);
                doCopperDrop(item, block);
            }
            case GRANITE, DIORITE, ANDESITE -> {
                block.setType(Material.AIR);
                e.setCancelled(true);
                block.getWorld().dropItem(block.getLocation(), new ItemStack(Material.COBBLESTONE));
            }
            case OAK_LEAVES, SPRUCE_LEAVES, BIRCH_LEAVES, JUNGLE_LEAVES, ACACIA_LEAVES, DARK_OAK_LEAVES -> {
                int var0 = item.getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS);
                if (RANDOM.nextInt(Math.max(1, 200 - var0 * 20)) < 1) {
                    e.setCancelled(true);
                    block.setType(Material.AIR);
                    block.getWorld().dropItem(block.getLocation(), new ItemStack(Material.APPLE));
                }
            }
            case LAPIS_ORE, DEEPSLATE_LAPIS_ORE -> {
                block.setType(Material.AIR);
                e.setCancelled(true);
                block.getWorld().dropItem(block.getLocation(), new ItemStack(Material.EXPERIENCE_BOTTLE, 1));
                if (RANDOM.nextInt(5) < 1) {
                    ExperienceOrb xp = block.getWorld().spawn(block.getLocation(), ExperienceOrb.class);
                    xp.setExperience(1);
                }
            }
        }
    }

    @EventHandler
    public void onEnchant(InventoryOpenEvent e) {
        if (!ManhuntConfiguration.Fun.fastMine) return;
        if (e.getInventory().getType() == InventoryType.ENCHANTING) {
            e.getInventory().setItem(1, new ItemStack(Material.LAPIS_LAZULI, 64));
        }
    }

    @EventHandler
    public void onEnchant(InventoryCloseEvent e) {
        if (!ManhuntConfiguration.Fun.fastMine) return;
        if (e.getInventory().getType() == InventoryType.ENCHANTING) {
            e.getInventory().setItem(1, null);
        }
    }

    @EventHandler
    public void onEnchant(InventoryClickEvent e) {
        if (!ManhuntConfiguration.Fun.fastMine) return;
        Inventory inv = e.getClickedInventory();
        if (inv == null) return;
        if (inv.getType() == InventoryType.ENCHANTING && e.getSlot() == 1) {
            e.setCancelled(true);
        }
    }

    private void doIronDrop(ItemStack item, Block block) {
        if (item == null) return;
        boolean canMine = switch (item.getType()) {
            case STONE_PICKAXE, IRON_PICKAXE, DIAMOND_PICKAXE, NETHERITE_PICKAXE -> true;
            default -> false;
        };
        if (canMine) {
            if (item.getEnchantmentLevel(Enchantment.SILK_TOUCH) > 0) {
                block.getWorld().dropItem(block.getLocation(), new ItemStack(Material.IRON_ORE));
            } else {
                block.getWorld().dropItem(block.getLocation(), new ItemStack(Material.IRON_INGOT, randomFortuneDrop(item.getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS))));
                if (RANDOM.nextInt(10) < 7) {
                    ExperienceOrb xp = block.getWorld().spawn(block.getLocation(), ExperienceOrb.class);
                    xp.setExperience(1);
                }
            }
        }
    }

    private void doGoldDrop(ItemStack item, Block block) {
        if (item == null) return;
        boolean canMine = switch (item.getType()) {
            case IRON_PICKAXE, DIAMOND_PICKAXE, NETHERITE_PICKAXE -> true;
            default -> false;
        };
        if (canMine) {
            if (item.getEnchantmentLevel(Enchantment.SILK_TOUCH) > 0) {
                block.getWorld().dropItem(block.getLocation(), new ItemStack(Material.GOLD_ORE));
            } else {
                block.getWorld().dropItem(block.getLocation(), new ItemStack(Material.GOLD_INGOT, randomFortuneDrop(item.getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS))));
                ExperienceOrb xp = block.getWorld().spawn(block.getLocation(), ExperienceOrb.class);
                xp.setExperience(1);
            }
        }
    }

    private void doCopperDrop(ItemStack item, Block block) {
        if (item == null) return;
        boolean canMine = switch (item.getType()) {
            case STONE_PICKAXE, IRON_PICKAXE, DIAMOND_PICKAXE, NETHERITE_PICKAXE -> true;
            default -> false;
        };
        if (canMine) {
            if (item.getEnchantmentLevel(Enchantment.SILK_TOUCH) > 0) {
                block.getWorld().dropItem(block.getLocation(), new ItemStack(Material.COPPER_ORE));
            } else {
                block.getWorld().dropItem(block.getLocation(), new ItemStack(Material.COPPER_INGOT, randomFortuneDrop(item.getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS))));
                ExperienceOrb xp = block.getWorld().spawn(block.getLocation(), ExperienceOrb.class);
                xp.setExperience(1);
            }
        }
    }

    private int randomFortuneDrop(int level) {
        if (level < 1) return 1;
        int num = RANDOM.nextInt(level + 2);
        return Math.max(level + 1 - num, 1);
    }
}
